package cn.janescott.inner.space.shiro.filter;

import cn.janescott.inner.space.shiro.token.UsernamePasswordCodeToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 帐号、密码、验证码
 *
 * @author scott
 * @date 2018/7/31
 */
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    private static final String VERIFY_CODE = "vCode";

    public static final String DEFAULT_ERROR_VALUE_ATTRIBUTE_NAME = "shiroLoginFailureValue";

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);
        boolean rememberMe = isRememberMe(request);
        String host = getHost(request);
        String vCode = getVerifyCode(request);
        return createToken(username, password, rememberMe, host, vCode);
    }

    /**
     * @param request 请求
     * @param ae      异常
     * @see FormAuthenticationFilter#setFailureAttribute(ServletRequest, AuthenticationException)
     * 默认情况下只将类名存到request的attribute中
     */
    @Override
    protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
        super.setFailureAttribute(request, ae);
        String message = ae.getMessage();
        request.setAttribute(DEFAULT_ERROR_VALUE_ATTRIBUTE_NAME, message);
    }

    private AuthenticationToken createToken(String username, String password,
                                            boolean rememberMe, String host, String vCode) {
        return new UsernamePasswordCodeToken(username, password, rememberMe, host, vCode);
    }

    /**
     * 获取验证码
     *
     * @param request 请求
     * @return 验证码
     */
    private String getVerifyCode(ServletRequest request) {
        return WebUtils.getCleanParam(request, VERIFY_CODE);
    }

    public CustomFormAuthenticationFilter(String loginUrl) {
        super();
        setLoginUrl(loginUrl);
    }
}
